package com.dashan.frontend.client.widgets;

import static com.dashan.Constants.COUNT;
import static com.dashan.Constants.POSITION_ACC;
import static com.dashan.Constants.POSITION_DESC;
import static com.dashan.Constants.POSITION_LAT;
import static com.dashan.Constants.POSITION_LNG;
import static com.dashan.Constants.SESSIONID;
import static com.dashan.Constants.STATUS;
import static com.dashan.Constants.SUCCESS;
import static com.dashan.Constants.USERNAME;

import java.util.Date;

import com.dashan.frontend.client.DashanCookie;
import com.dashan.frontend.client.event.GeoItemSelectedEvent;
import com.dashan.frontend.client.event.GeoItemSelectedHandler;
import com.dashan.frontend.client.util.DashanRequestBuilder;
import com.dashan.frontend.client.util.DashanXmlReader;
import com.dashan.frontend.client.util.GoogleMap;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.maps.client.geocode.Geocoder;
import com.google.gwt.maps.client.geocode.LocationCallback;
import com.google.gwt.maps.client.geocode.Placemark;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.ExtElement;
import com.gwtext.client.core.Position;
import com.gwtext.client.data.DateFieldDef;
import com.gwtext.client.data.FieldDef;
import com.gwtext.client.data.Record;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.StringFieldDef;
import com.gwtext.client.data.XmlReader;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.form.FormPanel;
import com.gwtext.client.widgets.form.TextField;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.GridView;

public class MyPanel extends Composite {

    private Panel root = new Panel();
    private Button postLocation = new Button("更新位置");
    private Panel postingLocationPanel = new Panel();
    private TextField desc = new TextField("描述");
    private Button cancelPost = new Button("取消");
    private Button confirmPost = new Button("确认");
    
    private FormPanel postingStatusPanel = new FormPanel();
    private TextField statusText = new TextField("我的状态");
    private Button postStatus = new Button("发布");
    private GeoGridPanel historyGird;
    private RecordDef recordDef = new RecordDef(new FieldDef[] {
            new StringFieldDef("description"), 
            new DateFieldDef("updatetime")
    });
    
    private MainPanel main;
    private Marker myLocation;
    public MyPanel(MainPanel main) {
        this.main = main;

        root.setBorder(false);
        root.add(postLocation);
    
        FormPanel postingLocationFormPanel = new FormPanel();
        postingLocationFormPanel.setBorder(false);
        postingLocationFormPanel.setLabelAlign(Position.RIGHT);
        postingLocationFormPanel.add(desc);
        postingLocationFormPanel.add(confirmPost);
        postingLocationFormPanel.add(cancelPost);
        
        postingStatusPanel.setLabelAlign(Position.RIGHT);
        postingStatusPanel.setMargins(10, 0, 0, 0);
        postingStatusPanel.add(statusText);
        postingStatusPanel.add(postStatus);
        postingLocationPanel.add(postingLocationFormPanel);
        initHistoryGrid();
        postingLocationPanel.hide();
        
        root.add(postingLocationPanel);
        root.add(postingStatusPanel);
        
        cancelPost.addListener(new ButtonListenerAdapter() {
           @Override
            public void onClick(Button button, EventObject e) {
               if (myLocation != null) {
                   MyPanel.this.main.getGoogleMap().getMap().removeOverlay(myLocation);
               }
               postingLocationPanel.hide();
               postLocation.show();
           }
        });

        confirmPost.addListener(new ButtonListenerAdapter() {
            @Override
            public void onClick(Button button, EventObject e) {
                confirmLocatoin();
            }
        });
        
        postLocation.addListener(new ButtonListenerAdapter() {
            @Override
            public void onClick(Button button, EventObject e) {
                super.onClick(button, e);
                postLocation();
                postLocation.hide();
                postingLocationPanel.show();
                loadHistoryPositions();
            }
        });
        
        postStatus.addListener(new ButtonListenerAdapter() {
            @Override
            public void onClick(Button button, EventObject e) {
                super.onClick(button, e);
                postStatus();
            }
        });

        root.setPaddings(10);
        initWidget(root);
    }
    
    private void loadHistoryPositions() {
        historyGird.clearData(); 
        DashanRequestBuilder builder = new DashanRequestBuilder("/getpositionhistory");
        builder.addUserParam();
        builder.addParameter(COUNT, "10");
        
        try {
            builder.sendRequest(new RequestCallback() {
                
                @Override
                public void onResponseReceived(Request request, Response response) {
                    if (Response.SC_OK == response.getStatusCode()) {
                        Record[] res = DashanXmlReader.fetchFromXml(response.getText(), 
                                new XmlReader("position", new RecordDef(new FieldDef[] {
                                     new StringFieldDef("description"),
                                     new StringFieldDef("timestamp_long"),
                                     new StringFieldDef("lng_lat_acc")
                                })));
                        
                        for (final Record r : res) {
                            final com.dashan.frontend.client.model.Position pos = 
                                new com.dashan.frontend.client.model.Position
                                (r.getAsString("lng_lat_acc"), 
                                    new Date(Long.parseLong(r.getAsString("timestamp_long"))));
                            MarkerOptions opt = MarkerOptions.newInstance(GoogleMap.ICON);
                            final Marker m = new Marker(LatLng.newInstance(pos.getLatitude(), pos
                                    .getLongitude()), opt);
                            if (r.getAsString("description") == null) {
                                Geocoder coder = new Geocoder();
                                coder.getLocations(m.getLatLng(), new LocationCallback() {
                                    
                                    @Override
                                    public void onSuccess(JsArray<Placemark> locations) {
                                       if (locations.length() > 0) {
                                           historyGird.addGeoRecord(new GeoGridPanel.GeoRecord(
                                                   recordDef.createRecord(new Object[] {
                                                           locations.get(0).getAddress(), 
                                                           pos.getTimestamp()
                                                   }), m));           
                                       }
                                    }
                                    
                                    @Override
                                    public void onFailure(int statusCode) {
                                    }
                                });
                            } else {
                                historyGird.addGeoRecord(new GeoGridPanel.GeoRecord(
                                        recordDef.createRecord(new Object[] {
                                                r.getAsString("description"), 
                                                pos.getTimestamp()}), m));
                            }
                        }
                    } else {
                        Window.alert(response.getStatusText());
                    }
                }
                
                @Override
                public void onError(Request request, Throwable exception) {
                    Window.alert(exception.getMessage());
                }
            });
        } catch (RequestException e) {
            Window.alert(e.getMessage());
        }
    }
    public void onShow() {
        postingLocationPanel.hide();
        postLocation.show();
    }
    
    private void initHistoryGrid() {
        historyGird = new GeoGridPanel(main.getGoogleMap(), recordDef);
        ColumnConfig desc = new ColumnConfig("历史位置", "description", 1, true);
        ColumnModel columnModel = new ColumnModel(new ColumnConfig[] {desc});
        
        historyGird.setHeight(300);
        historyGird.setWidth(275);
        historyGird.setMargins(10, 0, 0, 0);
        historyGird.setColumnModel(columnModel);
        
        GridView view = new GridView();
        view.setForceFit(true);
        historyGird.setView(view);
        
        historyGird.setItemSelectedHandler(new GeoItemSelectedHandler() {
            
            @Override
            public void onGeoItemSelected(GeoItemSelectedEvent event) {
                Marker m = event.getGeoRecord().getMarker();
                if (m != null && myLocation != null) {
                    myLocation.setLatLng(m.getLatLng());
                }
            }
        });
        
        postingLocationPanel.add(historyGird);
    }
    
    private void postLocation() {
        MarkerOptions opt = MarkerOptions.newInstance();
        opt.setDraggable(true);
        myLocation = new Marker(main.getGoogleMap().getMap().getCenter(), opt);
        myLocation.setDraggingEnabled(true);
        main.getGoogleMap().getMap().addOverlay(myLocation);
    }
    
    private void postStatus() {
        DashanRequestBuilder builder = new DashanRequestBuilder("/poststatus");
        DashanCookie cookie = DashanCookie.load();
        builder.addParameter(USERNAME, cookie.getUserName());
        builder.addParameter(SESSIONID, cookie.getSessionId());
        builder.addParameter(STATUS, statusText.getText());
        
        final ExtElement el = postingLocationPanel.getEl();
        if (el != null) {
            el.mask("正在上传...");
        }
        try {
            builder.sendRequest(new RequestCallback() {
                
                @Override
                public void onResponseReceived(Request request, Response response) {
                    if (Response.SC_OK == response.getStatusCode()) {
                        if (response.getText().contains(SUCCESS)) {
                            Window.alert("状态已更新!");
                        }
                    } else {
                        Window.alert(response.getStatusText());
                    }
                }
                
                @Override
                public void onError(Request request, Throwable exception) {
                    Window.alert(exception.getMessage());
                }
            });
        } catch (RequestException e) {
            Window.alert(e.getMessage());
        } finally {
            if (el != null) {
                el.unmask();
            }
        }
        
    }
    
    private void confirmLocatoin() {
        DashanRequestBuilder builder = new DashanRequestBuilder("/postposition");
        builder.addUserParam();
        builder.addParameter(POSITION_LAT, myLocation.getLatLng().getLatitude() + "");
        builder.addParameter(POSITION_LNG, myLocation.getLatLng().getLongitude() + "");
        builder.addParameter(POSITION_ACC, 0.0 + "");
        builder.addParameter(POSITION_DESC, desc.getText());
        
        final ExtElement el = postingLocationPanel.getEl();
        if (el != null) {
            el.mask("正在上传...");
        }
        try {
            builder.sendRequest(new RequestCallback() {
                
                @Override
                public void onResponseReceived(Request request, Response response) {
                    if (Response.SC_OK == response.getStatusCode()) {
                        if (response.getText().contains(SUCCESS)) {
                            if (myLocation != null) {
                                MyPanel.this.main.getGoogleMap().getMap().removeOverlay(myLocation);
                            }
                            Window.alert("位置已更新!");
                            postingLocationPanel.hide();
                            postLocation.show();
                        }
                    } else {
                        Window.alert(response.getStatusText());
                    }
                }
                
                @Override
                public void onError(Request request, Throwable exception) {
                    Window.alert(exception.getMessage());
                }
            });
        } catch (RequestException e) {
            Window.alert(e.getMessage());
        } finally {
            if (el != null) {
                el.unmask();
            }
        }
    }
}
